package org.agony2d.gpu.core {
	import flash.display3D.Context3D;
	import flash.geom.Matrix;
	import flash.geom.Matrix3D;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	import org.agony2d.core.agony_internal;
	import org.agony2d.debug.Logger;
	import org.agony2d.gpu.effects.EffectAA;
	import org.agony2d.gpu.FusionAA;
	import org.agony2d.gpu.supportClasses.programs.ProgramProxy;
	import org.agony2d.gpu.supportClasses.textures.FullTexture;
	import org.agony2d.notify.Notifier;
	
	use namespace agony_internal;
	
	[Event(name = "press",   type = "org.agony2d.notify.AEvent")]
	
	[Event(name = "release", type = "org.agony2d.notify.AEvent")]
	
	[Event(name = "over",    type = "org.agony2d.notify.AEvent")]
	
	[Event(name = "leave",   type = "org.agony2d.notify.AEvent")]
	
	[Event(name = "move",    type = "org.agony2d.notify.AEvent")]
	
	[Event(name = "click",   type = "org.agony2d.notify.AEvent")]
	
	/** [ NodeAA ]
	 *  [◆]
	 *  	1.  x × y
	 *  	2.  pivotX × pivotY
	 *  	3.  scaleX × scaleY × rotation
	 *  	4.  alpha
	 *  	5.  visible × interactive
	 *  	6.  world
	 *  	7.  fusion
	 *  	8.  effects
	 *  [◆◆]
	 *  	1.  globalToLocal × localToGlobal
	 *  	2.  collide
	 *  	3.  setCollisionMethod
	 *  	4.  kill
	 *  [★]
	 *  	a.  注意!! collide，不可在未进行任何渲染前使用...!!
	 */
public class NodeAA extends Notifier {
	
	public function NodeAA() {
		super(null)
		m_x = m_y = m_pivotX = m_pivotY = m_rotation = 0.0
		m_scaleX = m_scaleY = m_alpha = m_cachedAlpha = 1.0
	}
	
	public function get x() : Number {
		return m_x
	}
	
	public function set x( v:Number ) : void {
		if (m_x != v) {
			m_x = v
			m_altered = true
		}
	}
	
	public function get y() : Number {
		return m_y
	}
	
	public function set y( v:Number ) : void {
		if (m_y != v) {
			m_y = v
			m_altered = true
		}
	}
	
	public function get pivotX() : Number {
		return m_pivotX
	}
	
	public function set pivotX( v:Number ) : void {
		if (m_pivotX != v) {
			m_pivotX = v
			m_altered = true
		}
	}
	
	public function get pivotY() : Number {
		return m_pivotY
	}
	
	public function set pivotY( v:Number ) : void {
		if (m_pivotY != v) {
			m_pivotY = v
			m_altered = true
		}
	}
	
	public function get rotation():Number {
		return m_rotation
	}
	
	public function set rotation( v:Number ) : void {
		if (m_rotation != v) {
			m_rotation = v
			m_altered = true
		}
	}
	
	public function get scaleX():Number {
		return m_scaleX
	}
	
	public function set scaleX( v:Number ) : void {
		if (m_scaleX != v) {
			m_scaleX = v
			m_altered = true
		}
	}
	
	public function get scaleY():Number {
		return m_scaleY
	}
	
	public function set scaleY( v:Number ) : void {
		if (m_scaleY != v) {
			m_scaleY = v
			m_altered = true
		}
	}
	
	public function get alpha() : Number {
		return m_alpha
	}
	
	public function set alpha( v:Number ) : void {
		m_alpha = v
	}
	
	public function get visible() : Boolean {
		return !m_invisible
	}
	
	public function set visible( b:Boolean ) : void {
		m_invisible = !b
	}
	
	public function get interactive() : Boolean {
		return !m_intouchable
	}
	
	public function set interactive( b:Boolean ) : void {
		m_intouchable = !b
	}
	
	public function get world() : WorldAA {
		return m_world
	}
	
	public function get fusion() : NodeAA {
		return m_parent
	}
	
	public function get effects() : Array {
		return m_effects ? m_effects.concat() : []
	}
	
	public function set effects( v:Array ) : void {
		m_effects = v && v.length ? v : null
	}
	
	/** overwrite */
	public function globalToLocal( globalX:Number, globalY:Number, result:Point = null ) : Point {
		return null
	}
	
	/** overwrite */
	public function localToGlobal( localX:Number, localY:Number, result:Point = null ) : Point {
		return null
	}
	
	public function collide( x:Number, y:Number, global:Boolean = true ) : Boolean {
		if (!global) {
			return this.checkCollisionNode(x, y, false)
		}
		this.doTransformToLocal(x, y)
		return this.checkCollisionNode(cachedPoint.x, cachedPoint.y, false)
	}
	
	/** callback( localX:Number, localY:Number, node:NodeAA ) : Boolean... */
	public function setCollisionMethod( v:Function ) : void {
		m_collisionMethod = v
	}
	
	public function kill() : void {
		if (m_parent) {
			m_parent.removeNode(this)
		}
		this.dispose()
	}
	
	
	agony_internal static var cachedMatrix:Matrix
	agony_internal static var cachedRect:Rectangle
	agony_internal static var cachedPoint:Point
	agony_internal static var g_fullWidth:int
	agony_internal static var g_fullHeight:int
	agony_internal static var g_orthoMatrix3d:Matrix3D
	
	agony_internal var m_x:Number
	agony_internal var m_y:Number
	agony_internal var m_pivotX:Number
	agony_internal var m_pivotY:Number
	agony_internal var m_scaleX:Number
	agony_internal var m_scaleY:Number
	agony_internal var m_rotation:Number
	agony_internal var m_alpha:Number
	agony_internal var m_cachedAlpha:Number
	
	agony_internal var m_matrix_A:Matrix = new Matrix // self
	agony_internal var m_matrix_B:Matrix = new Matrix // complex
	agony_internal var m_parent:NodeAA
	agony_internal var m_fullTex:FullTexture
	agony_internal var m_world:WorldAA
	agony_internal var m_collisionMethod:Function
	agony_internal var m_invisible:Boolean
	agony_internal var m_intouchable:Boolean
	agony_internal var m_altered:Boolean
	agony_internal var m_effects:Array
	
	
	
	agony_internal function identity() : void {
		m_x = m_y = m_pivotX = m_pivotY = m_rotation = 0.0
		m_scaleX = m_scaleY = m_alpha = m_cachedAlpha = 1.0
	}
	
	/** overwrite */
	agony_internal function dispose() : void {
		
	}
	
	/** overwrite，向下更新，双重矩阵缓存... */
	agony_internal function doUpdateDownward() : void {
		
	}
	
	/** overwrite，向上更新，获取世界级矩阵，直到WorldAA层结束... */
	agony_internal function doUpdateUpward() : void {
		
	}
	
	/** overwrite，单独获取自身矩阵... */
	agony_internal function updateByAlone() : void {
		
	}
	
	/** overwrite */
	agony_internal function attach( parent:NodeAA ) : void {
		
	}
	
	/** overwrite */
	agony_internal function removeNode( node:NodeAA ) : void {
		
	}
	
	/** overwrite */
	agony_internal function checkCollisionNode( globalX:Number, globalY:Number, forInteract:Boolean ) : NodeAA {
		return null
	}
	
	/** overwrite，坐标换算，内部使用 */
	agony_internal function doTransformToLocal( x:Number, y:Number ) : void {
		
	}
	
	/** overwrite */
	agony_internal function replaceInternalNode( replaced:Object, shell:Object ) : void {
		
	}
	
	/** overwrite */
	agony_internal function render( vertexChanged:Boolean ) : void {
		
	}
	
	/** overwrite，???? */
	agony_internal function doSetEffects() : void {
		if (m_effects && m_effects.length > 0) {
			
		}
	}
}
}